package org.reborn.engine.util

import scala.actors._
import Actor._

import org.reborn.utils.actors._ 
import ActorExceptionHandler._

/**
 * Wraps a SimpleRegistry with an actors implementation.
 * 
 * Thread-safe
 */
class ActorBasedRegistry[T] extends Registry[T]{
  private case class Register(obj:T);
  private case class Unregister(id:Int);
  private case class Get(id:Int);
  private case class Reregister(id:Int,obj:T);
  
  private var wrappedReg = new SimpleRegistry[T]() 
  
  private val reg =
	actor
	{
	  var data = ""
	  loop
	  {
	    react
	    {
	      case Register(obj) => def func():Int = wrappedReg.register(obj); reply( DeferThrow( func ) )
	      case Unregister(id) => def func():Unit = wrappedReg.unregister(id); reply( DeferThrow( func ) )
	      case Get(id) => def func():Option[T] = wrappedReg.get(id); reply( DeferThrow( func ) )
          case Reregister(id,obj) => def func():Unit = wrappedReg.reregister(id,obj); reply( DeferThrow( func ) )
	    }
	  }
	}
  
  def register(obj:T):Int = GetOrThrow[Int](reg !? (new Register(obj)))
  def unregister(id:Int):Unit = GetOrThrow[Unit](reg !? (new Unregister(id)))
  def get(id:Int):Option[T] = GetOrThrow[Option[T]](reg !? (new Get(id)))
  def reregister(id:Int,obj:T):Unit = GetOrThrow[Option[T]](reg !? (new Reregister(id,obj)))
}
